/* =========================================================
 * bootstrap-validation.js 
 * Original Idea: http:/www.newkou.org (Copyright 2012 Stefan Petre)
 * Updated by 不会飞的羊 (https://github.com/FateSheep/Validation-for-Bootstrap)
 * =========================================================
 *
 * Licensed under the  (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================= 
 * 2013-4-12 ，由云海飞舞 （yunhaifeiwu修改，为了区别原作品，该组件更名为
 * bt-validate
 *
 * ========================================================= */
!function($) {
    var obj;
    $.fn.validation = function(options) {
       this.each(function() {
            globalOptions = $.extend({}, $.fn.validation.defaults, options);
            //globalOptions.callback = callback;  
            obj=this;
            reg(obj);
        });
       //console.log(globalOptions);
    };
    
    $.fn.validation.defaults = {
        validRules : [
            {name: 'required', validate: function(value) {return ($.trim(value) == '');}, defaultMsg: '请输入内容。'},
            {name: 'number', validate: function(value) {return (!/^[0-9]\d*$/.test(value));}, defaultMsg: '请输入数字。'},
            {name: 'mail', validate: function(value) {return (!/^[a-zA-Z0-9]{1}([\._a-zA-Z0-9-]+)(\.[_a-zA-Z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+){1,3}$/.test(value));}, defaultMsg: '请输入邮箱地址。'},
            {name: 'char', validate: function(value) {return (!/^[a-z\_\-A-Z]*$/.test(value));}, defaultMsg: '请输入英文字符。'},
            {name: 'chartime', validate: function(value) {return (!/^[\_A-Z0-9]*$/.test(value));}, defaultMsg: '请输入正确字符。'},
            {name: 'chinese', validate: function(value) {return (!/^[\u4e00-\u9fff]$/.test(value));}, defaultMsg: '请输入汉字。'},
            {name: 'rpassword', validate: function(value) {return (!new RegExp($("form input[name='password']").val()).test(value));}, defaultMsg: '两次密码输入不一致。'},
            {name: 'ip', validate: function(value) {return (!/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test(value));}, defaultMsg: '请输有效IP。'},
            {name: 'port', validate: function(value) {return (!/^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/.test(value));}, defaultMsg: '端口请输入0-65535的整数。'},
            {name: 'char&number', validate: function(value) {return (!/^[a-zA-Z0-9]{1,}$/.test(value));}, defaultMsg: '请输入英文或数字。'},
            {name: 'char&number&point', validate: function(value) {return (!/^[a-zA-Z0-9.]{1,}$/.test(value));}, defaultMsg: '请输入英文或数字或点。'},
            {name: 'normalcharacter', validate: function(value) {return (!/^[a-zA-Z0-9_]{1,}$/.test(value));}, defaultMsg: '请输入英文数字或下划线。'},
            {name: 'positiveinteger', validate: function(value) {return (!/^[1-9][0-9]*$/.test(value));}, defaultMsg: '请输入正整数。'},
            {name: 'naturalNumber', validate: function(value) {return (!/(^[1-9][0-9]$)|(100$)|(^[0-9]$)$/.test(value));}, defaultMsg: '请输入小于等于100的自然数。'},
            {name: 'uri', validate: function(value) {
            	var strRegex = "^(/[0-9a-zA-Z_!~*'(){}.;?:@&=+$,%#-]+)+/?$";
            	var re = new RegExp(strRegex);
            	return (!re.test(value));}, defaultMsg: '请输入正确的URI格式。'},
            {name: 'address', validate: function(value) {
            	var strRegex = "^((https|http|ftp|rtsp|mms)://)"
            		+ "(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" // ftp的user@
            		+ "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184
            		+ "|" // 允许IP和DOMAIN（域名）
            		+ "([0-9a-z_!~*'()-]+\.)*" // 域名- www.
            		+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名
            		+ "[a-z]{2,6})" // first level domain- .com or .museum
            		+ "(:[0-9]{1,4})?" // 端口- :80
            		+ "((/?)|" // a slash isn't required if there is no file name
            		+ "(/[0-9a-z_!~*'(){}.;?:@&=+$,%#-]+)+/?)$";
            	var re = new RegExp(strRegex);
            	return (!re.test(value.toLowerCase()));}, defaultMsg: '请输有效地址。'},
	    	{name: 'idNumber', validate: function(code) {
	            var city={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外 "};
	            var tip = "";
	            var pass= true;
	            
	            if(!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)){
	                tip = "身份证号格式错误";
	                pass = false;
	            }
	            
	           else if(!city[code.substr(0,2)]){
	                tip = "地址编码错误";
	                pass = false;
	            }
	            else{
	                //18位身份证需要验证最后一位校验位
	                if(code.length == 18){
	                    code = code.split('');
	                    //∑(ai×Wi)(mod 11)
	                    //加权因子
	                    var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
	                    //校验位
	                    var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
	                    var sum = 0;
	                    var ai = 0;
	                    var wi = 0;
	                    for (var i = 0; i < 17; i++)
	                    {
	                        ai = code[i];
	                        wi = factor[i];
	                        sum += ai * wi;
	                    }
	                    var last = parity[sum % 11];
	                    if(parity[sum % 11] != code[17]){
	                        tip = "校验位错误";
	                        pass =false;
	                    }
	                }
	            }
	            return !pass;
	    	}, defaultMsg: '请输有效身份证号。'}
            
        ]
    };

    
    
    var formState = false, fieldState = false, wFocus = false, globalOptions = {}, extend = {};

    var validateField = function(field, valid) { // 验证字段
        var el = $(field), error = false, errorMsg = '',
        crule=(el.attr('btvd-el')==undefined)?null:el.attr('btvd-el').split(' '),
        msg = (el.attr('btvd-err')==undefined)?null:el.attr('btvd-err').split(' ');
        if(crule){
            if( ! eval(crule[0]).test(el.val()) ) {
                error = true;
                errorMsg =msg;
            }
            
        } else {
            for (i = 0; (i < valid.length) ; i++) {
                var x = true, flag = valid[i];
                if (flag.substr(0, 1) == '!') {
                    x = false;
                    flag = flag.substr(1, flag.length - 1);
                }



                var rules = globalOptions.validRules;
                for (j = 0; j < rules.length; j++) {
                    var rule = rules[j];
                    if (flag == rule.name) {
                        if (rule.validate.call(field, el.val()) == x) {
                            error = true;
                            errorMsg = (msg == null)?rule.defaultMsg:msg;
                            break;
                        }
                    }
                }

                if (error) {break;}
            }
        }
        
        //外部验证回调方法  
        if (!error && extend.callback){  
            var params={  
                msg:'',  
                err:error  
            };  
                         
            extend.callback(field,params);   
            error = params.err;     
            if (error && (msg==null || errorMsg=='')){  
                errorMsg = params.msg;  
            }  
            else if(params.msg!=''){  
                errorMsg = params.msg;  
            } 
            
        };
            

        var controls = el.parent().find('a');
        var len=controls.length;
        
        if (error) {
             var cls= (el.attr('btvd-class')==undefined)?null:el.attr('btvd-class').split(' ');
             if ( len<=0) {                
                el.after('  <a  style=" visibility:hidden;font-size:1px;line-height:1px !important;height:1px;" data-placement="bottom"  data-content="'+errorMsg+ '"  data-toggle="popover" href="#" >aa</a> ');
             }else{
            	 $(controls).attr("data-content",errorMsg);
             }
             el.next().popover("show");  
             var pop=el.parent().find(".popover"),pos=pop.offset();
             pos.top=pos.top-el.next().height();
             pop.offset(pos);             
             
             if (cls) pop.addClass("btvdclass");
          
        } else {
            controls.popover("hide"); 

        }
        return !error;
    };

    var reg=function(obj){
        $('input, textarea').each(function() {
            var el = $(this), valid = (el.attr('btvd-type')==undefined)?null:el.attr('btvd-type').split(' ');
            valid1 = (el.attr('btvd-el')==undefined)?null:el.attr('btvd-el').split(' ');
            if (valid != null && valid.length > 0   || valid1 != null && valid1.length > 0 ) {                       

                el.blur(function() { // 失去焦点时
                    validateField(this, valid);
                });
            }
        });
    }
	$.fn.validationForm = function(options) {
            formState = true;
            var validationError = false;
            $('input, textarea', this).each(function () {
                var el = $(this), valid = (el.attr('btvd-type')==undefined)?null:el.attr('btvd-type').split(' ');
                if (valid != null && valid.length > 0) {
                    if (!validateField(this, valid)) {
                        if (wFocus == false) {
                            scrollTo(0, el[0].offsetTop - 50);
                            wFocus = true;
                        }

                        validationError = true;
                    }
                }
            });

            wFocus = false;
            fieldState = true;

            if (validationError) {
                formState = false; 
                return false;
            }

            return true;


    };
    
    /**
     * 单个元素，手动调动校检
     */
    $.fn.valid = function(){
    	var validationError = false;
    	var el = $(this);
    	var valid = (el.attr('btvd-type')==undefined)?null:el.attr('btvd-type').split(' ');
    	if (valid != null && valid.length > 0) {
            if (!validateField(this, valid)) {
                validationError = true;
            }
        }
    	return validationError;   	
    }
    
    /**
     * 手动添加外部ajax校验
     */
    $.fn.extendAjax = function(callback){
    	extend.callback = callback;
    }
    
}(window.jQuery);